package com.zilu.digitaltwin.common.util;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;

import javax.net.ssl.SSLContext;

/**
 * @author :caijianbao
 * @date : 2023/1/2 22:28
 */
public class HttpClientUtils {


    private static final String QP_SEP_S = "/";
    private static final String HEAD_ACCEPT_LANGUAGE = "Accept-Language";

    private HttpClientUtils() {

    }

    public static HttpClient createHttpClient() {
        return createHttpClient(10000, 200);
    }


    public static HttpClient createHttpClient(int timeout, int maxConn) {
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).setConnectionRequestTimeout(timeout).build();
        return HttpClientBuilder.create().setMaxConnTotal(maxConn).setMaxConnPerRoute(maxConn).setDefaultRequestConfig(requestConfig).build();
    }

    public static CloseableHttpClient createHttpsClient() throws Exception {
        CloseableHttpClient client = createHttpsClient(20000, 200);
        return client;
    }

    public static CloseableHttpClient createHttpsClient(int timeout, int maxConn) {
        RequestConfig requestConfig = RequestConfig.custom()
                //socket的连接超时时间
                .setConnectTimeout(timeout)
                //socket读数据超时时间：从服务器获取响应数据的超时时间
                .setSocketTimeout(timeout)
                //从连接池中获取连接的超时时间
                .setConnectionRequestTimeout(timeout).build();
        try {
            SSLContext sslcontext = trustAllHttpsCertificates();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
                    NoopHostnameVerifier.INSTANCE);
            return HttpClients.custom()
                    //忽略ssl证书安全问题
                    .setSSLSocketFactory(sslsf)
                    //连接池中最大连接数
                    .setMaxConnTotal(maxConn)
                    //分配给一个路由的最大连接数
                    .setMaxConnPerRoute(maxConn)
                    .setDefaultRequestConfig(requestConfig).build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static SSLContext trustAllHttpsCertificates() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        return sc;
    }

    static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }

        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
    }


    public static String joinUrl(String... fragments) {
        if (ArrayUtils.isEmpty(fragments)) {
            return "";
        }
        if (fragments.length == 1) {
            return fragments[0];
        }
        int length = 0;
        for (String fragment : fragments) {
            length += fragment.length();
        }
        boolean hasSep = fragments[0].endsWith(QP_SEP_S);
        StringBuilder buf = new StringBuilder(length + 1);
        buf.append(fragments[0]);
        for (int i = 1; i < fragments.length; i++) {
            String fragment = fragments[i];
            if (org.apache.commons.lang3.StringUtils.isEmpty(fragment)) {
                continue;
            }
            if (hasSep) {
                if (fragment.startsWith(QP_SEP_S)) {
                    buf.append(fragment.substring(1));
                } else {
                    buf.append(fragment);
                }
            } else if (fragment.startsWith(QP_SEP_S)) {
                buf.append(fragment);
            } else {
                buf.append(QP_SEP_S);
                buf.append(fragment);
            }
            hasSep = fragment.endsWith(QP_SEP_S);
        }
        return buf.toString();
    }


}
